package com.hrms.domain;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.persistence.Transient;
import javax.servlet.http.HttpServletRequest;

import com.google.appengine.api.datastore.Key;
import com.hrms.cache.EmployeeCache;
import com.hrms.core.Constants;
import com.hrms.core.EmailMsg;
import com.hrms.core.Role;
import com.hrms.core.RoleManager;
import com.hrms.core.RoleManager.ROLE;
import com.hrms.core.TemplateManager.Templates;
import com.hrms.core.Utils;

@PersistenceCapable(detachable="true")
public class Employee extends BusinessObjectImpl {
	
	public static final String TYPE = Employee.class.getSimpleName();

	public Employee(Map<String, String[]> parameterMap)
			throws IllegalArgumentException, IllegalAccessException,
			ParseException {
		super(parameterMap);
	}

	public Employee(){
		super();
	}
	
	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	private Key key;
	
	@Persistent
	private String userId;
	@Persistent
	private String empNo;
	@Persistent
	private String initials;
	
	@Persistent
	private String name;
	@Persistent
	private Date joinedDate;
	@Persistent
	private String role;
	@Persistent	
	private Date createTimestamp;
	@Persistent
	private String createdByUser;
	@Persistent
	private String lastModifyUser;
	@Persistent
	private String team;
	@Persistent
	private String supervisor;
	@Persistent
	private String employmentType;
	@Persistent
	private Date endOfProbation;
	
	
	@Transient
	private Role changeRole;
	
	public static enum EmploymentType{
		Probation, Permenent
	}
	
	public String getNamer() {
		return userId+empNo;
	}

	@Override
	public String fireEvents(String userAction, HttpServletRequest request) throws Exception {
		if(userAction.equals(Constants.Action.NEW.toString())){
			Employee emp = BusinessObjectImpl.selectAsSingleResult(Employee.class, "where userId==:p0" , new Object[]{ getUserId().toLowerCase() });
			if(emp != null){
				return (newWarning("Employee Record Exists For "+ getUserId()));
			}
			
			emp = BusinessObjectImpl.selectAsSingleResult(Employee.class, "where initials==:p0" , new Object[]{ getInitials().toUpperCase() });
			if(emp != null){
				return (newWarning("Employee Record Exists For Initials "+ getInitials()));
			}
		}
		return (super.fireEvents(userAction, request));
	}

	@Override
	protected void performPostPersistEvents(String userAction,
			HttpServletRequest request) throws Exception {
		
		if( (userAction.equals(Constants.Action.NEW.toString())) || (userAction.equals(Constants.Action.EDIT.toString()))){
			EmployeeCache.getInstance().putInCache(getUserId(), this);
		}
		
		if(userAction.equals(Constants.Action.NEW.toString())){
						
			EmailMsg email = new EmailMsg();
			Employee acceptedUser = (Employee)request.getAttribute(Employee.class.getSimpleName());
			
		try{
			Map<String, Object> params = new HashMap<String, Object>();
			
			email.addRecipient(getUserId());			
			email.setSubject("Welcome");
			
			email.setTemplate(Templates.employeeWelcome);
			
			params.put("to", getName());
			params.put("user", acceptedUser.getName());
			params.put("acct", getUserId());
			params.put("appId", Constants.APP_ID);
			
			email.setParams(params);
			
		}catch(Exception e){			
			email.copyAdmin();
			email.setMsg("Failed to email new Employee for "+ getUserId());
		log.log(Level.SEVERE, "Failed to email new Employeefor "+ getUserId(), e);
		}finally{
			email.send();
		}
			
		}
		
		super.performPostPersistEvents(userAction, request);
	}

	@Override
	public void jdoPreStore()  {
		setCreateTimestamp(new Date());
		setUserId(userId.toLowerCase());
		setInitials(initials.toUpperCase());
		setSupervisor(supervisor.toLowerCase());
	}	

	public String validate() {
		String msg = "";
		StringBuffer warnings = new StringBuffer();

		/*
		 * if (!StringUtils.isNotBlank(description)) { msg="Description";
		 * warnings.append(newWarning(msg)); }else{ if
		 * (StringUtils.length(description) > 140) { msg =
		 * "Description length ( Should reside within 140 Chars )";
		 * warnings.append(newWarning(msg)); } }
		 */

		return warnings.toString();
	}
	public String getEmpNo() {
		return empNo;
	}

	public String getEmploymentType() {
		return employmentType;
	}

	public void setEmploymentType(String employmentType) {
		this.employmentType = employmentType;
	}

	public Date getEndOfProbation() {
		return endOfProbation;
	}

	public void setEndOfProbation(Date endOfProbation) {
		this.endOfProbation = endOfProbation;
	}

	public void setEmpNo(String empNo) {
		this.empNo = empNo;
	}

	public String getInitials() {
		return initials;
	}

	public void setInitials(String initials) {
		this.initials = initials;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Date getJoinedDate() {
		return joinedDate;
	}

	public void setJoinedDate(Date joinedDate) {
		this.joinedDate = joinedDate;
	}

	public Role getRole() {		
		return RoleManager.findRole(role);
	}
	
	public String getRolePlain() {		
		return role;
	}

	public void setRole(String role) {
		this.role = role;
	}

	public Date getCreateTimestamp() {
		return createTimestamp;
	}

	public void setCreateTimestamp(Date createTimestamp) {
		this.createTimestamp = createTimestamp;
	}

	public String getCreatedByUser() {
		return createdByUser;
	}

	public void setCreatedByUser(String createdByUser) {
		this.createdByUser = createdByUser;
	}

	public String getLastModifyUser() {
		return lastModifyUser;
	}

	public void setLastModifyUser(String lastModifyUser) {
		this.lastModifyUser = lastModifyUser;
	}

	public String getTeam() {
		return team;
	}

	public void setTeam(String team) {
		this.team = team;
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public Role getChangeRole() {
		return changeRole;
	}

	public void setChangeRole(Role changeRole) {
		this.changeRole = changeRole;
	}
	
	public static String makeSelect(String name, String selectedOption){
		List<Employee> values = selectAll(Employee.class, "order by name");
		return makeSelect(name, selectedOption, values);
	}
	
	public static String makeSelect(String name, String selectedOption, List<Employee> values){
		StringBuffer sb = new StringBuffer("<select ");
		sb.append(" id=\"").append(name).append("\" ").append(" name=\"")
				.append(name).append("\" >");
		
		for (Employee e : values) {
			sb.append("<option value=\"")
					.append(Utils.escapeHTML(e.getUserId()))
					.append("\"")
					.append((e.getUserId().equals(selectedOption)) ? "Selected"
							: Constants.EMPTY_STRING).append(">")
					.append(Utils.escapeHTML(e.getName()+("~")+(e.getEmpNo()))).append("</option>");
		}
		sb.append("</select>");
		return sb.toString();
	}

	public String getSupervisor() {
		return supervisor;
	}

	public void setSupervisor(String supervisor) {
		this.supervisor = supervisor;
	}

	public Key getKey() {
		return key;
	}
	
	public void setKey(Key key) {
		this.key = key;
	}
	
	public static Map<String, String> fetchMappedUserIds(){
		Map<String, String> temp = new HashMap<String, String>();		
		List<Employee> values = selectAll(Employee.class);
		for (Employee e : values) {
			temp.put(e.getUserId(), e.getName());
		}
		return temp;
	}
	
	public static Map<String, Employee> fetchMappedEmploee(){
		Map<String, Employee> temp = new HashMap<String, Employee>();		
		List<Employee> values = selectAll(Employee.class);
		for (Employee e : values) {
			temp.put(e.getUserId(), e);
		}
		return Collections.unmodifiableMap( temp );
	}
	
	public static List<String> getMailListByRole(ROLE eRole, Map<String, Employee> eMap){
		
		Collection<Employee> hrList = eMap != null ? eMap.values() : select(Employee.class, "where role=:p0", new Object[]{eRole.toString()});
		List<String> mailList = new ArrayList<String>();
		
		for(Employee e : hrList){
			mailList.add( e.getName() +"  <"+ e.getUserId() +">");
		}		
		return mailList;
	}
	
	public static List<String> getMailListByTeam(String eTeam){
		List<Employee> hrList = select(Employee.class, "where team==:p0", new Object[]{ eTeam });
		List<String> mailList = new ArrayList<String>();
		
		for(Employee e : hrList){
			mailList.add( e.getName() +"  <"+ e.getUserId() +">");
		}		
		return mailList;
	}
	
	
	// on testing- do not use it
	public static Employee getByUserId(String userId){
		userId = userId.toLowerCase();
		
		Employee emp = null;
		
		emp = EmployeeCache.getInstance().findInCache(userId);		
		if(emp!=null){
			return emp;
		}
		
		emp =  BusinessObjectImpl.selectAsSingleResult(Employee.class, "where userId==:p0" , new Object[]{ userId });
		if(emp!=null){
			EmployeeCache.getInstance().putInCache(userId, emp);			
		}
		
		return emp;
	}
	
	public static List<Employee> selectEmployeeByRole(String team){
		/*if(RoleManager.ROLE.SUPERVISOR.toString().equals(inRole)){
			return select(Employee.class, "where team=:p0 order by name ", Arrays.asList(team));
		}else */
		/*if(RoleManager.ROLE.HR.toString().equals(inRole)){
			return selectAll(Employee.class, "order by name");
		}*/
		// Normal users can see what their teams members doing
		return select(Employee.class, "where team==:p0 order by name ", new Object[]{team});
		//return null;
	}
	
	/*public static String makeIconSet(String inputName, String selectedValue, List<Employee> empList){
		if((empList != null) && (!empList.isEmpty())){
			StringBuilder sb = new StringBuilder();
			//<c:icon key="" intials="" selected="yes"></c:icon>
			for(Employee e : empList){
				sb.append("<c:icon key=\"")
				.append( KeyFactory.keyToString(e.getKey()) )
				.append("\" intials=\"")
				.append( e.getInitials() )
				.append("\" selected=\"")
				.append( selectedValue.equals(e.getUserId()))
				.append("\"></c:icon>");
			}
			return sb.toString();
		}		
		return null;
	}*/

}
